﻿using System;
using System.Collections.Generic;
using LuaInterface;
using Newtonsoft.Json;
using UnityEngine;

namespace Framework
{
    public partial class ResMgr
    {
        private static readonly string AbMainifestName = "allmanifest";
        private static readonly string AbMainifestPath = AbMainifestName;
        private static readonly string SingleBgAbTabPath = "singlebgabtab";
        private static readonly string InnerAbCfgName = "innerabnames";
        private static readonly string All2OneAbPath  = "assetName2AbName";
        
        /// <summary>
        /// 初始化Ab依赖关系的回调
        /// </summary>
        private GeneralCallBack _abDepInitCb;

        /// <summary>
        /// 初始化ab依赖关系
        /// </summary>
        /// <param name="initCallback"></param>
        public void InitAbDependencies(Action initCallback)
        {
            GeneralCallBack.GetOrReUse(ref _abDepInitCb, initCallback);
            string mainifestUrl = AbMainifestPath + FrameworkSettings.DataExt;
            Logger.Log($"ResMgr.InitAbDependencies, 开始加载ab汇总信息文件 mainifestUrl = {mainifestUrl} ");
            if (_assetCache.TryGetValue(mainifestUrl, out AssetItem assetItem))
            {
                Logger.Log($"ResMgr.InitAbDependencies, 第二次加载的时候, 先要清理掉 {mainifestUrl} 的缓存!");
                _assetCache.Remove(mainifestUrl);
                assetItem.DestroySelf();
                AssetItem.Recycle(ref assetItem);
            }
            GetNonAbAsset(FrameworkSettings.GetAssetFullConfigPath(mainifestUrl), AssetType.DATA, OnLoadedManifestOk);
        }
        
        private void OnLoadedManifestOk(AssetItem assetItem)
        {
            if (!assetItem.IsLoadSuccess)
            {
                Logger.LogError("ResMgr.OnLoadedManifestOk, ab依赖汇总信息加载失败!");
                return;
            }
            Logger.Log("ResMgr.OnLoadedManifestOk, assetItem = " + assetItem);
            _allMainifest = new AllManifest(assetItem);
            _abRefCountTab = new Dictionary<string, int>();
            foreach (string abName in _allMainifest.abLookTab.Keys)
            {
                foreach (string dep in _allMainifest.GetDirectDependencies(abName))
                {
                    if (_abRefCountTab.ContainsKey(dep))
                    {
                        _abRefCountTab[dep]++;
                        continue;
                    }
                    _abRefCountTab[dep] = 1;
                }
            }

            InitAllToOneAbTab();
        }
        
        private void InitAllToOneAbTab()
        {
            string all2OneAbPath = All2OneAbPath + FrameworkSettings.DataExt;
            Logger.Log($"ResMgr.InitAllToOneAbTab, 开始加载all to one的映射信息文件 All2OneAbPath = {all2OneAbPath} ");
            if (_assetCache.TryGetValue(all2OneAbPath, out AssetItem abTabAssetItem))
            {
                Logger.Log($"ResMgr.InitAllToOneAbTab, all2OneAbPath的映射信息文件第二次加载的时候, 先要清理掉 {all2OneAbPath} 的缓存!");
                _assetCache.Remove(all2OneAbPath);
                abTabAssetItem.DestroySelf();
                AssetItem.Recycle(ref abTabAssetItem);
            }
            GetNonAbAsset(FrameworkSettings.GetAssetFullConfigPath(all2OneAbPath), AssetType.DATA, OnLoadAll2OneAbOk);
        }

        private Dictionary<string, string> all2OneAbLookTab;
        private void OnLoadAll2OneAbOk(AssetItem assetItem)
        {
            if (!assetItem.IsLoadSuccess)
            {
                Logger.LogError("ResMgr.OnLoadAll2OneAbOk, all2OneAbPath 目录的ab映射关系加载失败!");
                return;
            }
            var configJson = UnityZipUtil.UnzipStr(assetItem.DataAsset);
            all2OneAbLookTab = JsonConvert.DeserializeObject<Dictionary<string, string>>(configJson);
            
            GeneralCallBack.InvokeAndRecycle(ref _abDepInitCb);
        }

        public bool IsAllToOneAsset(string assetName)
        {
            return all2OneAbLookTab.ContainsKey(FrameworkSettings.GetAssetNameInBundle(assetName));
        }

        public string GetAllToOneAbName(string assetName)
        {
            var key = FrameworkSettings.GetAssetNameInBundle(assetName);
            if (all2OneAbLookTab.TryGetValue(key, out var abName))
            {
                return abName;
            }

            Debug.LogError("all2OneAbLookTab not assetName : " + assetName);
            return assetName;
        }
    }
}